using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using T.FAS.Runtime.DataAccess.SPI;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataAccess.Common;

namespace T.FAS.Runtime.DataAccess.Engine
{
    class DOUpdateService : IUpdateService<DataObject>
    {
        public event ExecuteDataAccessAction Execute;
        public event BuildDataAccessActionContext BuildContext;

        public BatchUpdateResult BatchUpdateData(DataObject metadata, List<TRecord> data, Dictionary<string, object> exrParams = null)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 更新CDO数据
        /// </summary>
        /// <param name="metadata">元数据</param>
        /// <param name="data">通用结果对象</param>
        public TResult UpdateData(DataObject metadata, TRecord data, Dictionary<string, object> exrParams = null)
        {
            if (metadata == null)
                throw new FasException(DataAccessErrorCode.DataObject.NullValue, CommonStringClassEngine.DataModelService_MetaDataCannotBeNull);
            if (data == null)
                throw new FasException(DataAccessErrorCode.DataObject.NullValue, CommonStringClassEngine.DataModelService_TRecordCannotBeNull);
            
            var cdo = CDOConverter.Convert(metadata);
            var sqls = SQLBuilderFactory.CreateCDOSQLBuilder().ParseUpdateSql(cdo, data);

            var db = Kernel.DatabaseFactory.CreateDefaultDatabase();
            db.ExecuteSQLWithTransaction(sqls);
            return default;
        }

        /// <summary>
        /// 更新CDO数据
        /// </summary>
        /// <param name="metadata">元数据</param>
        /// <param name="childNodeId">节点ID</param>
        /// <param name="data">通用结果对象</param>
        public TResult UpdateData(DataObject metadata, string childNodeId, TRecord data, Dictionary<string, object> exrParams = null)
        {
            if (metadata == null)
                throw new FasException(DataAccessErrorCode.DataObject.NullValue, CommonStringClassEngine.DataModelService_MetaDataCannotBeNull);
            if (string.IsNullOrWhiteSpace(childNodeId))
                throw new FasException(DataAccessErrorCode.DataObject.NullValue, CommonStringClassEngine.CDODataUpdateService_ChildNodeIdCannotBeNull);
            if (data == null)
                throw new FasException(DataAccessErrorCode.DataObject.NullValue, CommonStringClassEngine.DataModelService_TRecordCannotBeNull);

            var cdo = CDOConverter.Convert(metadata);
            var cno = cdo.CompositeNodeObjects.FirstOrDefault(i => i.ID == childNodeId);
            if (cno == null)
            {
                throw new FasException(DataAccessErrorCode.DataObject.NullValue, CommonStringClassEngine.CDOService_CannotFindCNOInstance + childNodeId);
            }

            var sqls = SQLBuilderFactory.CreateCDOSQLBuilder().ParseUpdateSql(cdo, cno, data);

            var db = Kernel.DatabaseFactory.CreateDefaultDatabase();
            db.ExecuteSQLWithTransaction(sqls);
            return default;
        }
    }
}
